package com.rfid.project.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;

import biz.util.IdUtil;
import biz.util.ListUtil;
import biz.util.StringUtil;

import com.rfid.project.dao.AftersaleRecordDao;
import com.rfid.project.dao.AftersaleRecordWorktimeDao;
import com.rfid.project.dao.AftersaleTransferRecordDao;
import com.rfid.project.exception.CannotDelException;
import com.rfid.project.model.AftersaleRecord;
import com.rfid.project.model.Customer;
import com.rfid.project.model.People;
import com.rfid.project.model.Project;
import com.rfid.project.model.QAftersaleRecord;
import com.rfid.project.model.QAftersaleRecordWorktime;
import com.rfid.project.model.QAftersaleTransferRecord;
import com.mysema.query.BooleanBuilder;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Transactional
public class AftersaleRecordService{

	@Autowired
	private AftersaleRecordDao aftersaleRecordDao;
	
	private QAftersaleRecord $ = QAftersaleRecord.aftersaleRecord;
	
	@Autowired
	public void setAftersaleRecordDao(AftersaleRecordDao aftersaleRecordDao) {
		this.aftersaleRecordDao = aftersaleRecordDao;
	}

	@Autowired
	private AftersaleTransferRecordDao aftersaleTransferRecordDao;
	
	private QAftersaleTransferRecord $_1 = QAftersaleTransferRecord.aftersaleTransferRecord;
	
	@Autowired
	public void setAftersaleTransferRecordDao(AftersaleTransferRecordDao aftersaleTransferRecordDao) {
		this.aftersaleTransferRecordDao = aftersaleTransferRecordDao;
	}

	@Autowired
	private AftersaleRecordWorktimeDao aftersaleRecordWorktimeDao;

	private QAftersaleRecordWorktime $_2 = QAftersaleRecordWorktime.aftersaleRecordWorktime;

	@Autowired
	public void setAftersaleRecordWorktimeDao(
			AftersaleRecordWorktimeDao aftersaleRecordWorktimeDao) {
		this.aftersaleRecordWorktimeDao = aftersaleRecordWorktimeDao;
	}
	
	public List<AftersaleRecord> findAll(){
		return ListUtil.toList(aftersaleRecordDao.findAll());
	}
				
	public List<AftersaleRecord> findAll(
	Long registerPersonId,
	String issueDescription,
	String outOfWarrantySign,
	Date registerTimeBegin,
	Date registerTimeEnd,
	Date expectFinishDateBegin,
	Date expectFinishDateEnd,
	Long projectId,
	Long productId,
	Long customerId,
	String customerName,
	String contactPerson,
	String contactPersonTel,
	Long handlePersonId,
	Long aftersaleHandleTypeId,
	String status,
	Date actualFinishTimeBegin,
	Date actualFinishTimeEnd,
	String productSequenceNo,
	Long checkPersonId,
	Date checkTimeBegin,
	Date checkTimeEnd,
	Date returnDateBegin,
	Date returnDateEnd,
	Date finishDateBegin,
	Date finishDateEnd,
	Date deliveryDateBegin,
	Date deliveryDateEnd,
	String issueReason,
	String handleDescription,
	String handleCostDescription,
	String remark,
	String orderByAttribute	){
	BooleanBuilder condition = new BooleanBuilder();
	
	if(IdUtil.isNotEmpty(registerPersonId)){
		condition.and($.registerPerson.id.eq(registerPersonId));
	}
	
	if(StringUtil.isNotEmpty(issueDescription)){
		condition.and($.issueDescription.contains(issueDescription));
	}
	
	if(StringUtil.isNotEmpty(outOfWarrantySign)){
		condition.and($.outOfWarrantySign.contains(outOfWarrantySign));
	}
	
	if(registerTimeBegin != null){
		condition.and($.registerTime.after(registerTimeBegin));
	}
	
	if(registerTimeEnd != null){
		condition.and($.registerTime.before(registerTimeEnd));
	}
	
	if(expectFinishDateBegin != null){
		condition.and($.expectFinishDate.after(expectFinishDateBegin));
	}
	
	if(expectFinishDateEnd != null){
		condition.and($.expectFinishDate.before(expectFinishDateEnd));
	}
	
	if(IdUtil.isNotEmpty(projectId)){
		condition.and($.project.id.eq(projectId));
	}
	
	if(IdUtil.isNotEmpty(productId)){
		condition.and($.product.id.eq(productId));
	}
	
	if(IdUtil.isNotEmpty(customerId)){
		condition.and($.customer.id.eq(customerId));
	}
	
	if(StringUtil.isNotEmpty(customerName)){
		condition.and($.customerName.contains(customerName));
	}
	
	if(StringUtil.isNotEmpty(contactPerson)){
		condition.and($.contactPerson.contains(contactPerson));
	}
	
	if(StringUtil.isNotEmpty(contactPersonTel)){
		condition.and($.contactPersonTel.contains(contactPersonTel));
	}
	
	if(IdUtil.isNotEmpty(handlePersonId)){
		condition.and($.handlePerson.id.eq(handlePersonId));
	}
	
	if(IdUtil.isNotEmpty(aftersaleHandleTypeId)){
		condition.and($.aftersaleHandleType.id.eq(aftersaleHandleTypeId));
	}
	
	if(StringUtil.isNotEmpty(status)){
		condition.and($.status.contains(status));
	}
	
	if(actualFinishTimeBegin != null){
		condition.and($.actualFinishTime.after(actualFinishTimeBegin));
	}
	
	if(actualFinishTimeEnd != null){
		condition.and($.actualFinishTime.before(actualFinishTimeEnd));
	}
	
	
	if(StringUtil.isNotEmpty(productSequenceNo)){
		condition.and($.productSequenceNo.contains(productSequenceNo));
	}
	
	if(IdUtil.isNotEmpty(checkPersonId)){
		condition.and($.checkPerson.id.eq(checkPersonId));
	}
	
	if(checkTimeBegin != null){
		condition.and($.checkTime.after(checkTimeBegin));
	}
	
	if(checkTimeEnd != null){
		condition.and($.checkTime.before(checkTimeEnd));
	}
	
	if(returnDateBegin != null){
		condition.and($.returnDate.after(returnDateBegin));
	}
	
	if(returnDateEnd != null){
		condition.and($.returnDate.before(returnDateEnd));
	}
	
	if(finishDateBegin != null){
		condition.and($.finishDate.after(finishDateBegin));
	}
	
	if(finishDateEnd != null){
		condition.and($.finishDate.before(finishDateEnd));
	}
	
	if(deliveryDateBegin != null){
		condition.and($.deliveryDate.after(deliveryDateBegin));
	}
	
	if(deliveryDateEnd != null){
		condition.and($.deliveryDate.before(deliveryDateEnd));
	}
	
	if(StringUtil.isNotEmpty(issueReason)){
		condition.and($.issueReason.contains(issueReason));
	}
	
	
	if(StringUtil.isNotEmpty(handleDescription)){
		condition.and($.handleDescription.contains(handleDescription));
	}
	
	
	if(StringUtil.isNotEmpty(handleCostDescription)){
		condition.and($.handleCostDescription.contains(handleCostDescription));
	}
	
	if(StringUtil.isNotEmpty(remark)){
		condition.and($.remark.contains(remark));
	}
	
	
	return ListUtil.toList(aftersaleRecordDao.findAll(condition));
	}		

	public Page<AftersaleRecord> findAll(
			Long registerPersonId,
			String issueDescription,
			String outOfWarrantySign,
			Date registerTimeBegin,
			Date registerTimeEnd,
			Date expectFinishDateBegin,
			Date expectFinishDateEnd,
			Long projectId,
			Long productId,
			Long customerId,
			String customerName,
			String contactPerson,
			String contactPersonTel,
			Long handlePersonId,
			Long aftersaleHandleTypeId,
			String status,
			Date actualFinishTimeBegin,
			Date actualFinishTimeEnd,
			String productSequenceNo,
			Long checkPersonId,
			Date checkTimeBegin,
			Date checkTimeEnd,
			Date returnDateBegin,
			Date returnDateEnd,
			Date finishDateBegin,
			Date finishDateEnd,
			Date deliveryDateBegin,
			Date deliveryDateEnd,
			String issueReason,
			String handleDescription,
			String handleCostDescription,
			String remark,
			int pageNumber, int pageSize,String sortAttribute,String orderDirection) {
			BooleanBuilder condition = new BooleanBuilder();
	
			if(IdUtil.isNotEmpty(registerPersonId)){
				condition.and($.registerPerson.id.eq(registerPersonId));
			}
			if(StringUtil.isNotEmpty(issueDescription)){
				condition.and($.issueDescription.contains(issueDescription));
			}
			if(StringUtil.isNotEmpty(outOfWarrantySign)){
				condition.and($.outOfWarrantySign.contains(outOfWarrantySign));
			}
			if(registerTimeBegin != null){
				condition.and($.registerTime.after(registerTimeBegin));
			}
			
			if(registerTimeEnd != null){
				condition.and($.registerTime.before(registerTimeEnd));
			}
			if(expectFinishDateBegin != null){
				condition.and($.expectFinishDate.after(expectFinishDateBegin));
			}
			
			if(expectFinishDateEnd != null){
				condition.and($.expectFinishDate.before(expectFinishDateEnd));
			}
			if(IdUtil.isNotEmpty(projectId)){
				condition.and($.project.id.eq(projectId));
			}
			if(IdUtil.isNotEmpty(productId)){
				condition.and($.product.id.eq(productId));
			}
			if(IdUtil.isNotEmpty(customerId)){
				condition.and($.customer.id.eq(customerId));
			}
			if(StringUtil.isNotEmpty(customerName)){
				condition.and($.customerName.contains(customerName));
			}
			if(StringUtil.isNotEmpty(contactPerson)){
				condition.and($.contactPerson.contains(contactPerson));
			}
			if(StringUtil.isNotEmpty(contactPersonTel)){
				condition.and($.contactPersonTel.contains(contactPersonTel));
			}
			if(IdUtil.isNotEmpty(handlePersonId)){
				condition.and($.handlePerson.id.eq(handlePersonId));
			}
			if(IdUtil.isNotEmpty(aftersaleHandleTypeId)){
				condition.and($.aftersaleHandleType.id.eq(aftersaleHandleTypeId));
			}
			if(StringUtil.isNotEmpty(status)){
				condition.and($.status.contains(status));
			}
			if(actualFinishTimeBegin != null){
				condition.and($.actualFinishTime.after(actualFinishTimeBegin));
			}
			
			if(actualFinishTimeEnd != null){
				condition.and($.actualFinishTime.before(actualFinishTimeEnd));
			}
			if(StringUtil.isNotEmpty(productSequenceNo)){
				condition.and($.productSequenceNo.contains(productSequenceNo));
			}
			if(IdUtil.isNotEmpty(checkPersonId)){
				condition.and($.checkPerson.id.eq(checkPersonId));
			}
			if(checkTimeBegin != null){
				condition.and($.checkTime.after(checkTimeBegin));
			}
			
			if(checkTimeEnd != null){
				condition.and($.checkTime.before(checkTimeEnd));
			}
			if(returnDateBegin != null){
				condition.and($.returnDate.after(returnDateBegin));
			}
			
			if(returnDateEnd != null){
				condition.and($.returnDate.before(returnDateEnd));
			}
			if(finishDateBegin != null){
				condition.and($.finishDate.after(finishDateBegin));
			}
			
			if(finishDateEnd != null){
				condition.and($.finishDate.before(finishDateEnd));
			}
			if(deliveryDateBegin != null){
				condition.and($.deliveryDate.after(deliveryDateBegin));
			}
			
			if(deliveryDateEnd != null){
				condition.and($.deliveryDate.before(deliveryDateEnd));
			}
			if(StringUtil.isNotEmpty(issueReason)){
				condition.and($.issueReason.contains(issueReason));
			}
			if(StringUtil.isNotEmpty(handleDescription)){
				condition.and($.handleDescription.contains(handleDescription));
			}
			if(StringUtil.isNotEmpty(handleCostDescription)){
				condition.and($.handleCostDescription.contains(handleCostDescription));
			}
			if(StringUtil.isNotEmpty(remark)){
				condition.and($.remark.contains(remark));
			}
	
			Sort sortObject = null;
			if(StringUtil.isEmpty(sortAttribute)){
				sortObject = new Sort(Direction.DESC, "id");
			}else{
				sortObject = new Sort(Direction.fromStringOrNull(orderDirection),sortAttribute);
			}
			
			PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize, sortObject);
			return aftersaleRecordDao.findAll(condition, pageRequest);
	}
	
	
	
	public AftersaleRecord getAftersaleRecord(Long id){
		return aftersaleRecordDao.getOne(id);
	}
	
	public void deleteAftersaleRecord(Long id) throws CannotDelException{
		if (this.findAftersaleTransfterRecordByAftersaleRecord(id)) {
			throw new CannotDelException("无法删除，被售后流转记录引用！");
		} else if(this.findAftersaleRecordWorktimeByAftersaleRecord(id)){
			throw new CannotDelException("无法删除，被售后记录工时引用！");
		}else{
			aftersaleRecordDao.delete(id);
		}
	}
	
	private boolean findAftersaleTransfterRecordByAftersaleRecord(Long aftersaleRecordId){
		BooleanBuilder condition = new BooleanBuilder();
		condition.and($_1.aftersaleRecord.id.eq(aftersaleRecordId));
		return this.aftersaleTransferRecordDao.count(condition) > 0;
	}
	
	private boolean findAftersaleRecordWorktimeByAftersaleRecord(Long aftersaleRecordId){
		BooleanBuilder condition = new BooleanBuilder();
		condition.and($_2.aftersaleRecord.id.eq(aftersaleRecordId));
		return this.aftersaleRecordWorktimeDao.count(condition) > 0;
	}

	public void saveAftersaleRecord(AftersaleRecord aftersaleRecord) {
		aftersaleRecordDao.save(aftersaleRecord);
	}

	public Set<People> findRegisterPersonByProject(Project project){
		BooleanBuilder condition = new BooleanBuilder();
		condition.and($.project.id.eq(project.getId()));
		Set<People> peoples = new HashSet<People>();
		List<AftersaleRecord> aftersaleRecords = ListUtil.toList(this.aftersaleRecordDao.findAll(condition));
		for (AftersaleRecord aftersaleRecord : aftersaleRecords) {
			peoples.add(aftersaleRecord.getRegisterPerson());
		}
		return peoples;
	}
	
	public Set<People> findHandlePersonsByProject(Project project){
		BooleanBuilder condition = new BooleanBuilder();
		condition.and($.project.id.eq(project.getId()));
		Set<People> peoples = new HashSet<People>();
		List<AftersaleRecord> aftersaleRecords = ListUtil.toList(this.aftersaleRecordDao.findAll(condition));
		for (AftersaleRecord aftersaleRecord : aftersaleRecords) {
			peoples.add(aftersaleRecord.getHandlePerson());
		}
		return peoples;
	}
	
	public Set<People> findCheckPersonsByProject(Project project){
		BooleanBuilder condition = new BooleanBuilder();
		condition.and($.project.id.eq(project.getId()));
		Set<People> peoples = new HashSet<People>();
		List<AftersaleRecord> aftersaleRecords = ListUtil.toList(this.aftersaleRecordDao.findAll(condition));
		for (AftersaleRecord aftersaleRecord : aftersaleRecords) {
			peoples.add(aftersaleRecord.getCheckPerson());
		}
		return peoples;
	}
	
	public Set<Customer> findCustomer(Project project){
		BooleanBuilder condition = new BooleanBuilder();
		condition.and($.customer.id.eq(project.getId()));
		List<AftersaleRecord> aftersaleRecords = ListUtil.toList(this.aftersaleRecordDao.findAll(condition));
		Set<Customer> customers = new HashSet<Customer>();
		for (AftersaleRecord aftersaleRecord : aftersaleRecords) {
			customers.add(aftersaleRecord.getCustomer());
		}
		return customers;
	}

	public AftersaleRecord findOne(Long id) {
		return this.aftersaleRecordDao.findOne(id);
	}
	
}
		
